iT邦幫忙

2022 iThome 鐵人賽

DAY 3
0
Software Development

離開C#新手村的最後試煉系列 第 3

試煉3 - Debug 時,是怎麼看變數內容的呢

  • 分享至 

  • xImage
  •  

開始試煉

開發中 在Debug模式下觀察程式是否如想像中一般的執行
會需要觀察變數內容 現在為何對吧 就像是下面範例

static void Main(string[] args)
{
    var list = new List<Product>
    {
        new Product{Id=1,Tags=new List<Tag>{new Tag{Id=61,Name="TA"}},Title="PA",Price=100},
        new Product{Id=2,Tags=new List<Tag>{new Tag{Id=61,Name="TB"}},Title="PB",Price=110},
        new Product{Id=3,Tags=new List<Tag>{new Tag{Id=61,Name="TC"}},Title="PC",Price=130}
    };
}
public class Product
{
    public int Id { get; set; }
    public List<Tag> Tags { get; set; }
    public string Title { get; set; }
    public int Price { get; set; }
}

public class Tag
{
    public int Id { get; set; }
    public string Name { get; set; }
}

list 放的是class 在Visual Studio Debug 時就會看到這樣的畫面

還要一個一個展開才能看到內容

Product class 如果有加上

public override string ToString()
{
    return $"{Title} - {Price}";
}


就可以看到ToString的結果
不過其實VS有一個屬性 專門就是用來顯示Debug時
加上 DebuggerDisplay (nq 是 no-quotes 的意思)

[DebuggerDisplay("{Title,nq}:{Price,nq}")]
public class Product
{
    public int Id { get; set; }
    public List<Tag> Tags { get; set; }
    public string Title { get; set; }
    public int Price { get; set; }
}

那Tags怎麼呈現呢 (也可以看一下沒加上nq的樣子)
[DebuggerDisplay("{Title} - {Tags[0].Name} :{Price,nq}")]

如果{Tags[0].Name}改成{Tags}
[DebuggerDisplay("{Title} - {Tags} :{Price,nq}")]
{Tags} 會變成Count=1

支援一層套一層的DebuggerDisplay

[DebuggerDisplay("{Title} - {Tags[0]} :{Price,nq}")]
public class Product

[DebuggerDisplay("Tag : {Id} {Name,nq}")]
public class Tag

還有{Title} 可以玩很多變化像是
{Title.ToLower()}
{IsEmpty ? 0 : Count}

如果覺得太複雜的時候還可以這樣做

[DebuggerDisplay("{DD}")]
public class Product
{ 
    private string DD
    {
        get { return $"{Id} {Title} {Price} Tags:{Tags.Count}"; }
    }
}

這樣在偵錯時 追資料內容時 就會容易許多

PS.有個套件ozcode 是這方面的專家 不過被收購後 就不知道有沒有持續經營了

延伸試煉

DebuggerTypeProxy 這我比較少用 就看下面連結吧
C# 使用 DebuggerDisplay 和 DebuggerTypeProxy 來呈現 Debugger 相關資訊

結束試煉

現在學會DebuggerDisplay看List或class要檢查資料時 就方便許多

參考
Simplify debugging with DebuggerDisplay attribute dotNET

自我試煉

寫完這篇後就順便練習 DebuggerTypeProxy
可以自己寫如何呈現展開後資訊

static void Main(string[] args)
{
    var list = new List<Product>
    {
        new Product{
            Id=1,
            Tags=new List<Tag>
            {
                new Tag{Id=61,Name="TA"},
                new Tag{Id=62,Name="TB"},
                new Tag{Id=63,Name="TC"}
            },
            Title="PA",
            Price=100},
    };
}
[DebuggerDisplay("{DD}")]
[DebuggerTypeProxy(typeof(TagDebugView))]
public class Product
{
    public int Id { get; set; }
    public List<Tag> Tags { get; set; }
    public string Title { get; set; }
    public int Price { get; set; }
    private class TagDebugView
    {
        private readonly Product _product;
        public TagDebugView(Product product)
        {
            _product = product;
        }
        [DebuggerBrowsable(DebuggerBrowsableState.Collapsed)]
        public string TDV => String.Join(",",_product.Tags.Select(x => x.Name));
    }
    private string DD
    {
        get { return $"{Id} {Title} {Price} Tags:{Tags.Count}"; }
    }
    public override string ToString()
    {
        return $"{Title} - {Price}";
    }
}
[DebuggerDisplay("Tag : {Id} {Name,nq}")]
public class Tag
{
    public int Id { get; set; }
    public string Name { get; set; }
}


上一篇
試煉2 - appSettings 由簡單讀取到進階應用
下一篇
試煉4 - 用過 default 和 params 嗎
系列文
離開C#新手村的最後試煉30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言